import { reactive } from "vue";
import { createGlobalState } from "@vueuse/core";
import { cloneDeep } from "lodash-es";

import { useConfigs } from "./config";
import { useWorkspace } from "./workspace";
import useSelection from "./selection";

import {
  FormItem,
  ParsedComponent,
  ParsedFormItem,
  ParsedRegularExp,
  ParsedValidator,
} from "@/types";

const formItemTemplate: FormItem = {
  label: "",
  field: "",
  required: true,
  component: "",
  regExps: [],
  validators: [],
  span: 0,
};

export const useFormItems = createGlobalState(() => {
  const { opAreaConfig } = useConfigs();
  const { workspace } = useWorkspace();

  let lastDefaultCol = opAreaConfig.defaultCol;
  const formItems = reactive<FormItem[]>([]);

  function increaseFormItems(count: number) {
    const span = 24 / lastDefaultCol;
    for (let i = 1; i <= count; i++) {
      formItems.push({
        ...formItemTemplate,
        span,
        component: workspace.components[0]?.id || "",
      });
    }
  }

  function resetFormItems() {
    const { defaultRow, defaultCol } = opAreaConfig;
    lastDefaultCol = defaultCol;
    formItems.length = 0;
    increaseFormItems(defaultRow * defaultCol);
  }

  function removeFormItem(index: number) {
    if (formItems.length === 1) return;
    formItems.splice(index, 1);
  }

  return {
    formItems,
    increaseFormItems,
    resetFormItems,
    removeFormItem,
    ...useSelection(formItems),
  };
});

export function normalizeFormItems(items: FormItem[]) {
  let propNo = 1;
  const { getResourceById } = useWorkspace();

  return items
    .filter((item) => item.label.trim())
    .map<ParsedFormItem>((item) => {
      const { label, field, component, regExps, validators, ...rest } = item;
      return {
        ...rest,
        label: `${label.trim()}`,
        field: field.trim() || `prop${propNo++}`,
        component: getResourceById<ParsedComponent>(component),
        validators: validators.map<ParsedValidator>(getResourceById),
        regExps: regExps.map<ParsedRegularExp>(getResourceById),
      };
    });
}

export function refineFormItems(items: ParsedFormItem[]) {
  const customComponents = cloneDeep(
    items.filter((item) => item.component.custom).map((item) => item.component)
  );
  const builtInComponents = cloneDeep(
    items.filter((item) => !item.component.custom).map((item) => item.component)
  );

  const customComponentImportDeclarations = cloneDeep(
    customComponents.map((c) => c.import)
  );

  const builtInComponentImportDeclarations = cloneDeep(
    builtInComponents.map((c) => c.import)
  );

  const rulesImportDeclarations = cloneDeep(
    items
      .map((item) => {
        const { regExps, validators } = item;
        return [
          ...regExps.map((re) => re.import),
          ...validators.map((v) => v.import),
        ];
      })
      .flat()
  );

  return {
    customComponents,
    builtInComponents,
    customComponentImportDeclarations,
    builtInComponentImportDeclarations,
    rulesImportDeclarations,
  };
}
